﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service.Domain.Interfaces
{
    public interface IDbContext : IDisposable
    {
        IDbContext UseTransaction();

        IDbContext WithTimeout(int timeout);

        Task<IEnumerable<T>> QueryAsync<T>(string sql, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true);

        Task<IEnumerable<TResult>> QueryAsync<T, T2, TResult>(string sql, Func<T, T2, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<IEnumerable<TResult>> QueryAsync<T, T2, T3, TResult>(string sql, Func<T, T2, T3, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<IEnumerable<TResult>> QueryAsync<T, T2, T3, T4, TResult>(string sql, Func<T, T2, T3, T4, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<IEnumerable<TResult>> QueryAsync<T, T2, T3, T4, T5, TResult>(string sql, Func<T, T2, T3, T4, T5, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<IEnumerable<TResult>> QueryAsync<T, T2, T3, T4, T5, T6, TResult>(string sql, Func<T, T2, T3, T4, T5, T6, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<IEnumerable<TResult>> QueryAsync<T, T2, T3, T4, T5, T6, T7, TResult>(string sql, Func<T, T2, T3, T4, T5, T6, T7, TResult> func, object parameters = null, CommandType cmdType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<T> QueryFirstAsync<T>(string sql, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true);

        Task<TResult> QueryFirstAsync<T1, T2, TResult>(string sql, Func<T1, T2, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstAsync<T1, T2, T3, TResult>(string sql, Func<T1, T2, T3, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstAsync<T1, T2, T3, T4, TResult>(string sql, Func<T1, T2, T3, T4, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstAsync<T1, T2, T3, T4, T5, TResult>(string sql, Func<T1, T2, T3, T4, T5, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstAsync<T1, T2, T3, T4, T5, T6, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, T7, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<T> QueryFirstOrDefaultAsync<T>(string sql, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true);

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, TResult>(string sql, Func<T1, T2, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, T3, TResult>(string sql, Func<T1, T2, T3, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, T3, T4, TResult>(string sql, Func<T1, T2, T3, T4, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, T3, T4, T5, TResult>(string sql, Func<T1, T2, T3, T4, T5, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, T3, T4, T5, T6, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QueryFirstOrDefaultAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, T7, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<T> QuerySingleAsync<T>(string sql, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true);

        Task<TResult> QuerySingleAsync<T1, T2, TResult>(string sql, Func<T1, T2, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleAsync<T1, T2, T3, TResult>(string sql, Func<T1, T2, T3, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleAsync<T1, T2, T3, T4, TResult>(string sql, Func<T1, T2, T3, T4, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleAsync<T1, T2, T3, T4, T5, TResult>(string sql, Func<T1, T2, T3, T4, T5, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleAsync<T1, T2, T3, T4, T5, T6, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, T7, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<T> QuerySingleOrDefaultAsync<T>(string sql, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true);

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, TResult>(string sql, Func<T1, T2, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, T3, TResult>(string sql, Func<T1, T2, T3, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, T3, T4, TResult>(string sql, Func<T1, T2, T3, T4, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, T3, T4, T5, TResult>(string sql, Func<T1, T2, T3, T4, T5, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, T3, T4, T5, T6, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<TResult> QuerySingleOrDefaultAsync<T1, T2, T3, T4, T5, T6, T7, TResult>(string sql, Func<T1, T2, T3, T4, T5, T6, T7, TResult> func, object parameters = null, CommandType commandType = CommandType.Text, bool buffered = true, string splitOn = "Id");

        Task<int> InsertAsync(string sql, object parameters);

        Task<int> UpdateAsync(string sql, object parameters);

        Task<int> DeleteAsync(string sql, object parameters);

        void Rollback();

        void Commit();
    }
}
